const fs = require('fs')
const path = require('path')
const resolve = (...args) => path.resolve(__dirname, ...args)

const logger = require('pino')({
  prettyPrint: {
    colorize: true,
    translateTime: 'yyyy-mm-dd HH:MM:ss.l',
    ignore: 'pid,hostname'
  }
})

const express = require('express')
const { createProxyMiddleware } = require('http-proxy-middleware')

const middlewares = [
  require('connect-history-api-fallback')(),
  require('compression')(),
  express.json(),
  express.urlencoded({ extended: true }),
  require('helmet')({
    contentSecurityPolicy: false,
    referrerPolicy: { policy: 'strict-origin-when-cross-origin' }
  })
]

function createApp(app, port, publicPath) {
  // health check
  app.get('/health', function (req, res) {
    res.sendStatus(200)
  })

  // proxy
  app.use([
    '/v1/graphql',
    '/api',
    '/upload',
    '/gf'
  ], createProxyMiddleware({
    target: 'http://127.0.0.1:7001',
    onError: (err, req, res) => res.send(503),
    xfwd: true
  }))

  app.use([
    '/web-apps',
    '/7.0.1-37'
  ], createProxyMiddleware({
    target: 'http://127.0.0.1:7001',
    onError: (err, req, res) => res.send(503)
  }))

  app.use([
    '/unsafe',
    '/cache',
    '/sdkjs',
    '/doc'
  ], createProxyMiddleware({
    target: 'http://127.0.0.1:7001',
    onError: (err, req, res) => res.send(503),
    changeOrigin: true,
    xfwd: true
  }))

  const appMiddlewares = [
    require('serve-favicon')(
      resolve(`${publicPath}/favicon.ico`)
    ),
    ...middlewares
  ]

  for (let key in appMiddlewares) {
    app.use(appMiddlewares[key])
  }

  // gzip
  app.get([
    '/favicon.ico',
    '/static*'
  ], require('express-static-gzip')(
    resolve(publicPath), {
      enableBrotli: true,
      maxAge: '1y',
      orderPreference: ['br', 'gzip', 'deflate'],
      customCompressions: [{
        encodingName: 'br',
        fileExtension: 'gz'
      }]
    }
  ))

  const html = fs.readFileSync(resolve(`${publicPath}/index.html`), 'utf-8')

  app.get('*', (req, res) => res.send(html))

  app.listen(port, (err) => {
    if (err) return logger.error(`Server starting error ${err}`)
    logger.info(`Server is running at http://127.0.0.1:${port}`)
  })
}

// www
// createApp(express(), process.env.WWW_SERVER_PORT || 8018, 'public/www')

// admin
createApp(express(), process.env.ADMIN_SERVER_PORT || 8019, 'public/admin')
